/*
 * Copyright (c) 2006 Consolidated Court Automation Programs
 * All rights reserved.
 */
package example;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.Iterator;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

/**
 * Much of this code is taken from the Java Web Services Tutortial
 * (http://java.sun.com/webservices/docs/1.1/tutorial/doc/index.html)
 * 
 * Only a single example because in the pattern doesn't change with the request
 * (create an input, send the request, navigate the output tree)
 * 
 * Note that the username and password are encoded in the URL.
 */
public class Client
{
    /** The username provided by CCAP */
    private static final String USER = "exampleuser";

    /** The password provided by CCAP */
    private static final String PASSWORD = "examplepass1/examplepass2";

    /** The namespace of the WCCA2 SOAP service */
    private static final String SERVICE_NS =
        "urn:soap.wcca2.ccap.courts.state.wi.us";

    /** The host to contact */
    private static final String SERVICE_HOST = "wcca.wicourts.gov";

    /** WCCA2 service location */
    private static final String SERVICE_URI = "/services/WCCA2";

    public static void main(String[] args)
    {
        SOAPConnection conn = null;
        try
        {
            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            conn = factory.createConnection();

            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage message = messageFactory.createMessage();

            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();

            // remove header
            SOAPHeader header = envelope.getHeader();
            header.detachNode();

            SOAPBody body = envelope.getBody();

            Name bodyName = envelope.createName("searchCases", "m", SERVICE_NS);

            SOAPBodyElement elem = body.addBodyElement(bodyName);

            SOAPElement input = elem.addChildElement("input", "m");

            addRequestContent(envelope, input);

            SOAPMessage response = conn.call(message, getRequestURL());

            conn.close();
            conn = null;

            walkBody(response.getSOAPPart().getEnvelope());
        }
        catch (SOAPException e)
        {
            e.printStackTrace();
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (conn != null)
            {
                try
                {
                    conn.close();
                }
                catch (SOAPException e)
                {
                    // ignore
                }
            }
        }
    }

    private static void walkBody(SOAPEnvelope env) throws SOAPException
    {
        SOAPBody body = env.getBody();
        if (body.hasFault())
        {
            dumpFault(body.getFault());
        }
        else
        {
            displayCaseList(env, body);
        }
    }

    private static void displayCaseList(SOAPEnvelope env, SOAPBody body)
        throws SOAPException
    {
        String lineSeparator = System.getProperty("line.separator");

        Iterator i =
            body.getChildElements(
                env.createName("searchCasesResponse", null, SERVICE_NS));
        SOAPElement searchCasesResponse = (SOAPElement) i.next();
        i =
            searchCasesResponse.getChildElements(
                env.createName("CaseSearchResult", null, SERVICE_NS));
        SOAPElement caseSearchResult = (SOAPElement) i.next();
        i =
            caseSearchResult.getChildElements(
                env.createName("caseInfoList", null, SERVICE_NS));

        StringBuffer result = new StringBuffer();

        result.append("--------");
        result.append(lineSeparator);

        Name caseNoName = env.createName("caseNo", null, SERVICE_NS);
        Name captionName = env.createName("caption", null, SERVICE_NS);
        int count = 0;
        while (i.hasNext())
        {
            count++;

            SOAPElement caseInfo = (SOAPElement) i.next();
            String caseNo =
                ((SOAPElement) caseInfo.getChildElements(caseNoName).next())
                    .getValue();
            String caption =
                ((SOAPElement) caseInfo.getChildElements(captionName).next())
                    .getValue();
            result.append(caseNo);
            result.append(' ');
            result.append(caption);
            result.append(lineSeparator);
        }

        result.append("--------");
        result.append(lineSeparator);

        System.out.println("Retrieved " + count + " results");
        System.out.print(result.toString());
    }

    private static void dumpFault(SOAPFault fault)
    {
        System.out.println("Received SOAP fault");
        System.out.println(
            "Fault Actor: "
                + (fault.getFaultActor() == null
                    ? "<empty>"
                    : fault.getFaultActor()));
        System.out.println(
            "Fault Code: "
                + (fault.getFaultCode() == null
                    ? "<empty>"
                    : fault.getFaultCode()));
        System.out.println(
            "Fault String: "
                + (fault.getFaultString() == null
                    ? "<empty>"
                    : fault.getFaultString()));
    }

    private static URL getRequestURL() throws MalformedURLException
    {
        StringBuffer url = new StringBuffer("http://");
        url.append(URLEncoder.encode(USER));
        url.append(':');
        url.append(URLEncoder.encode(PASSWORD));
        url.append('@');
        url.append(SERVICE_HOST);
        url.append(SERVICE_URI);
        return new URL(url.toString());
    }

    private static void addRequestContent(
        SOAPEnvelope envelope,
        SOAPElement input)
        throws SOAPException
    {
        input.addChildElement("countyNo", "m").addTextNode(
            "44");

        SOAPElement caseRange =
            input.addChildElement("caseRange", "m");

        caseRange.addChildElement("year", "m").addTextNode(
            "2001");
        caseRange.addChildElement("caseType", "m").addTextNode(
            "CF");
        caseRange.addChildElement("start", "m").addTextNode(
            "50");
        caseRange.addChildElement("end", "m").addTextNode("60");
    }
}
